/** 
Copyright (c) 2010, Sheikh Abdul Wahid Ahmed
Details @ http://extremecodeworld.codeplex.com/license
**/

using System;
 using System.Xml;
using EXtremecode.Logging;
using System.Collections;
namespace CodeGenerator.Definitions
{
	
	/// <summary>
	/// Summary description for Repository.
	/// </summary>
	
	
	public enum GeneratedFileType
	{
		Table,Once,Copy,CopyFolder	
	};
	public class Repository
	{
		private XmlDocument xmlDoc;
		private Repository.SessionFiles sessionFiles;
		private Repository.GeneratedFiles generatedFiles;
		private Repository.Security securityRelated;
		private bool isSecurityDefined= true;
		public Repository.SessionFiles SessionFilesList
		{
			get
			{
				if(sessionFiles==null) 
				{
					XmlNodeList nodes=xmlDoc.GetElementsByTagName("SessionFiles");
					if(nodes.Count==0)
					{
						throw Logger.Write(new Exception("SessionFiles element is not present"));
					}
					sessionFiles=  new SessionFiles((XmlElement)nodes[0]);
				}
				return sessionFiles;
			}
		}

		public Repository.GeneratedFiles  GeneratedFilesList
		{
			get
			{
				if(generatedFiles==null) 
				{
					XmlNodeList nodes=xmlDoc.GetElementsByTagName("GeneratedFiles");
					if(nodes.Count==0)
					{
						throw Logger.Write(new Exception("GeneratedFiles element is not present"));
					}
					generatedFiles=  new GeneratedFiles((XmlElement)nodes[0]);
				}
				return generatedFiles;
			}
		}
		
		public Repository.Security SecurityRelated
		{
			get
			{
				if(securityRelated==null && isSecurityDefined) 
				{
					XmlNodeList nodes=xmlDoc.GetElementsByTagName("Security");
					if(nodes.Count==0)
					{
						isSecurityDefined=false;
					}
					else
					{
						securityRelated=  new Security((XmlElement)nodes[0]);
					}
				}
				return securityRelated;
			}
		}
		

		
		public Repository(XmlDocument xmlDoc)
		{
			this.xmlDoc=xmlDoc;
		}

		public string ProjectName
		{
			get
			{
				return this["projectName"];
			}
		}
		public string EntityDefinitionFile
		{
			get
			{
				return this["entityDefinitionFile"];
			}
		}
		public string EntityCustomFile
		{
			get
			{
				return this["entityCustomFile"];
			}
		}
		public string this [string key]
		{
			get
			{
				return (xmlDoc.DocumentElement.Attributes[key]==null)? string.Empty:
					xmlDoc.DocumentElement.Attributes[key].Value;
			}
		}

		#region Inner Class [SessionFiles]
		public class SessionFiles:IEnumerator
		{
			private XmlElement element;
			private File[] files;
			private int currentIndex=0;

			
				
			public SessionFiles(XmlElement element)
			{
				this.element=element;
			}
			
			
			
			public File this [int index]
			{
				get
				{
					if(files==null)
					{
						LoadFiles();
					}
					return files[index];
				}


			}
			private void LoadFiles()
			{
				XmlNodeList nodes=element.GetElementsByTagName("File");
				if(nodes.Count==0)
				{
					throw Logger.Write(new Exception("No session file is defined"));
				}
				ArrayList al=new ArrayList();
				foreach(XmlNode node in nodes)
				{
					al.Add(new File((XmlElement)node));
				}
				files=(File[])al.ToArray(typeof(File));
			}


			public void Reset()
			{
				currentIndex=0;
			}
			public bool MoveNext()
			{
				if(files == null)
				{
					LoadFiles();
				}
				return (files.Length != 0 && files.Length-1>=currentIndex); 
			}
			
			public object Current
			{
				get
				{
					return (files== null || files.Length==0)? null:
						files[currentIndex++];
				}
			}
			public int Count 
			{
				get
				{
					return (files ==null)? 0: files.Length;  
				}
			}
			public IEnumerator GetEnumerator()
			{
				Reset();
				return this;	
			}


			#region SessionFiles Inner Class [File]
			public class File
			{
				private XmlElement element;
				public File(XmlElement element)
				{
					this.element=element;
					
				}


				public string Name
				{
					get
					{
						return this["name"]; 
					}
				}
				public string this [string key]
				{
					get
					{
						return element.Attributes[key].Value;
					}
				}
			}

			
			#endregion

		}
		#endregion
		
		#region Inner Class [GeneratedFiles]
		public class GeneratedFiles:IEnumerator
		{
			
			#region GeneratedFiles Inner Class [File]
			public class File
			{
				private XmlElement element;
				public File(XmlElement element)
				{
					this.element=element;
					
				}


				public string Name
				{
					get
					{
						return this["name"]; 
						
					}
				}

				public bool MappCustomCode
				{
					get
					{
						return (this["mappCustomCode"]== "false")? false: true; 
						
					}
				}

				public bool Enabled
				{
					get
					{
						return (this["enabled"]== "false")? false: true; 
						
					}
				}

				public GeneratedFileType Type
				{
					get
					{
						string str=this["type"]; 
						GeneratedFileType type;
						try
						{
							type=(GeneratedFileType)Enum.Parse(typeof(GeneratedFileType),str,true); 
						}
						catch
						{
							throw Logger.Write(new Exception(
								string.Format("generated file type '{0}' is not valid",str)));
						}
						return type;
					}
					
				}
				public string CopyFile
				{
					get
					{
						return this["copyFile"]; 
					}
				}

				public string Condition
				{
					get
					{
						return this["cond"]; 
					}
				}

				public string[] sessionList
				{
					get
					{
						string str= this["sessionList"]; 
						return str.Split(',');
					}
				}

				public string this [string key]
				{
					get
					{
						XmlAttribute atb=  element.Attributes[key];
						return (atb==null)? string.Empty: atb.Value;  
					}
				}
			}
			#endregion

			private XmlElement element;
			private File[] files;
			private int currentIndex=0;

			public GeneratedFiles(XmlElement element)
			{
				this.element=element;
			}
			
			public File this [int index]
			{
				get
				{
					if(files==null)
					{
						LoadFiles();
					}
					return files[index];
				}


			}

			private void LoadFiles()
			{
				XmlNodeList nodes=element.GetElementsByTagName("File");
				if(nodes.Count==0)
				{
					throw Logger.Write(new Exception("No generated file is defined"));
				}
				ArrayList al=new ArrayList();
				foreach(XmlNode node in nodes)
				{
					al.Add(new File((XmlElement)node));
				}
				files=(File[])al.ToArray(typeof(File));
			}


			public void Reset()
			{
				currentIndex=0;
			}
			public bool MoveNext()
			{
				if(files == null)
				{
					LoadFiles();
				}
				return (files.Length != 0 && files.Length-1>=currentIndex); 
			}
			
			public object Current
			{
				get
				{
					return (files== null || files.Length==0)? null:
						files[currentIndex++];
				}
			}
			public int Count 
			{
				get
				{
					return (files ==null)? 0: files.Length;  
				}
			}
			public IEnumerator GetEnumerator()
			{
				Reset();
				return this;	
			}


		}
		#endregion

		#region Inner Class [Security]
		public class Security
		{
			private XmlElement element;
			Security.UserLogin userLoginInfo;
			Security.UserRole userRoleInfo;


			public Security(XmlElement element)
			{
				this.element=element;
			}

			public Security.UserLogin  UserLoginInfo
			{
				get
				{
					if(userLoginInfo==null) 
					{
						XmlNodeList nodes=element.GetElementsByTagName("UserLogin");
						if(nodes.Count==0)
						{
							throw Logger.Write(new Exception("UserLogin element is not present"));
						}
						userLoginInfo=  new UserLogin((XmlElement)nodes[0]);
					}
					return userLoginInfo;
				}
			}

			public Security.UserRole UserRoleInfo
			{
				get
				{
					if(userRoleInfo==null) 
					{
						XmlNodeList nodes=element.GetElementsByTagName("UserRole");
						if(nodes.Count==0)
						{
							throw Logger.Write(new Exception("UserRole element is not present"));
						}
						userRoleInfo=  new UserRole((XmlElement)nodes[0]);
					}
					return userRoleInfo;
				}
			}
		

			
			public class UserLogin
			{
				private XmlElement element;
				public UserLogin(XmlElement element)
				{
					this.element=element;
				}

				public string Entity
				{
					get
					{
						return this["entity"];
					}
				}
				public string UserIdField
				{
					get
					{
						return this["userIdField"];
					}
				}
				public string UserNameField
				{
					get
					{
						return this["userNameField"];
					}
				}
				public string PasswordField
				{
					get
					{
						return this["passwordField"];
					}
				}

				public string DefaultRoleIdField
				{
					get
					{
						return this["defaultRoleIdField"];
					}
				}

				public string RelatedRolesEntity
				{
					get
					{
						return this["relatedRolesEntity"];
					}
				}
				public string roleIdField
				{
					get
					{
						return this["roleIdField"];
					}
				}
				public string this [string key]
				{
					get
					{
						return (element.Attributes[key]==null)? string.Empty:
							element.Attributes[key].Value;
					}
				}
			}
			public class UserRole
			{
				private XmlElement element;
				public UserRole(XmlElement element)
				{
					this.element=element;
				}
				public string Entity
				{
					get
					{
						return this["entity"];
					}
				}

				public string roleIdField
				{
					get
					{
						return this["roleIdField"];
					}
				}

				public string roleNameField
				{
					get
					{
						return this["roleNameField"];
					}
				}

				public string homeModuleIdField
				{
					get
					{
						return this["homeModuleIdField"];
					}
				}


				public string relatedModulesEntity
				{
					get
					{
						return this["relatedModulesEntity"];
					}
				}

				public string moduleIdField
				{
					get
					{
						return this["moduleIdField"];
					}
				}

				

				public string this [string key]
				{
					get
					{
						return (element.Attributes[key]==null)? string.Empty:
							element.Attributes[key].Value;
					}
				}
			}
		}
		#endregion

		
	}
}
